package com.example.dense_rack_server.service.dataBackup;


import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.dense_rack_server.entity.BackupLog;
import com.example.dense_rack_server.entity.BackupTask;
import com.example.dense_rack_server.entity.NodeInfo;
import com.example.dense_rack_server.entityVo.dataBackup.BackupJobVO;
import com.example.dense_rack_server.entityVo.dataBackup.BackupReqVO;
import com.example.dense_rack_server.enums.BackupCategoryEnum;
import com.example.dense_rack_server.mapper.dataBackup.BackupTaskMapper;
import com.example.dense_rack_server.mapper.dataBackup.NodeInfoMapper;
import com.example.dense_rack_server.utils.DataBackup.MysqlTool;
import com.example.dense_rack_server.utils.DataBackup.quartz.QuartzManager;
import com.example.dense_rack_server.utils.ResponseModel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * MySQL连接信息 服务实现类
 * </p>
 *
 * @author 张彬
 * @since 2025-07-01
 */
@Service
public class NodeInfoService extends ServiceImpl<NodeInfoMapper, NodeInfo> {

    @Resource
    private NodeInfoMapper nodeInfoMapper;
    @Resource
    private BackupLogService backupLogService;
    @Autowired
    private MysqlTool mysqlTool;
    @Resource
    private BackupTaskMapper backupTaskMapper;
    @Resource
    private QuartzManager quartzManager;

    /**
     * 获取用户列表
     */
    public Map<String, Object> tableList(int page, int limit, String name, String host, String port) {
        IPage<Map<String, Object>> pageList = new Page<>(page, limit);//参数一是当前页，参数二是每页个数
        QueryWrapper<NodeInfo> wrapper = new QueryWrapper<>();
        if (StrUtil.isNotEmpty(name)) {
            wrapper.like("name", name);
        }
        if (StrUtil.isNotEmpty(host)) {
            wrapper.like("host", host);
        }
        if (StrUtil.isNotEmpty(port)) {
            wrapper.like("port", port);
        }
        wrapper.eq("del_flag", 0).orderByDesc("create_time");
        pageList = nodeInfoMapper.selectMapsPage(pageList, wrapper);
        Map<String, Object> map = new HashMap<>();
        map.put("code", 0);
        map.put("msg", "数据请求成功");
        map.put("count", pageList.getTotal());
        map.put("data", pageList.getRecords());
        return map;
    }

    public ResponseModel add(NodeInfo nodeInfo) {
        LambdaQueryWrapper<NodeInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(NodeInfo::getName, nodeInfo.getName());
        int count = this.count(queryWrapper);
        if (0 < count) {
            return ResponseModel.success("连接名已存在");
        }
        nodeInfoMapper.insert(nodeInfo);
        return ResponseModel.success("添加成功");
    }


    /**
     * 开始备份
     */
    public ResponseModel saveBackUp(BackupReqVO reqVO) {
        if (null == reqVO.getNodeId()) {
            return ResponseModel.fail("备份信息错误，请刷新后重试");
        }
        if (StringUtils.isBlank(reqVO.getDatabase())) {
            return ResponseModel.fail("请选择需要备份的数据库");
        }
        NodeInfo nodeInfo = this.baseMapper.selectById(reqVO.getNodeId());
        if (null == nodeInfo) {
            return ResponseModel.fail("备份信息错误，请刷新后重试");
        }
        // 组装备份参数
        BackupJobVO jobVO = getBackupJobVO(nodeInfo, reqVO);
        try {
            // 立即备份
            if (reqVO.getCategoryEnum().equals(BackupCategoryEnum.MANUAL)) {
                // 保存备份记录
                BackupLog backupLog = backupLogService.saveBackupLog(jobVO, BackupCategoryEnum.MANUAL);
                // 调用备份
                mysqlTool.saveBackUp(jobVO, backupLog);
                return ResponseModel.success("操作成功，请稍后在【备份记录】中查看");
            }
            // 定时备份
            else {
                if (StringUtils.isBlank(reqVO.getCron())) {
                    return ResponseModel.fail("请选择定时时间");
                }
//                if (!CronExpression.isValidExpression(reqVO.getCron())) {
//                    return ResponseModel.fail("请输入正确的cron表达式");
//                }
                String cronType = reqVO.getCron();
                String cron = "";
                String cronText = "";
                switch (cronType) {
                    case ("1"):
                        cron = BackupCategoryEnum.AUTO_HALF_HOUR.getCode();
                        cronText = BackupCategoryEnum.AUTO_HALF_HOUR.getMsg();
                        break;
                    case ("2"):
                        cron = BackupCategoryEnum.AUTO_HOUR.getCode();
                        cronText = BackupCategoryEnum.AUTO_HOUR.getMsg();
                        break;
                    case ("3"):
                        cron = BackupCategoryEnum.AUTO_NOON.getCode();
                        cronText = BackupCategoryEnum.AUTO_NOON.getMsg();
                        break;
                    case ("4"):
                        cron = BackupCategoryEnum.AUTO_MONDAY.getCode();
                        cronText = BackupCategoryEnum.AUTO_MONDAY.getMsg();
                        break;
                    case ("5"):
                        cron = BackupCategoryEnum.AUTO_FIRST_DAY.getCode();
                        cronText = BackupCategoryEnum.AUTO_FIRST_DAY.getMsg();
                        break;
                    case ("6"):
                        cron = BackupCategoryEnum.AUTO_FIFTEENTH_DAY.getCode();
                        cronText = BackupCategoryEnum.AUTO_FIFTEENTH_DAY.getMsg();
                        break;
                    case ("7"):
                        cron = BackupCategoryEnum.AUTO_LAST_DAY.getCode();
                        cronText = BackupCategoryEnum.AUTO_LAST_DAY.getMsg();
                        break;
                    case ("8"):
                        cron = BackupCategoryEnum.AUTO_MINUTE.getCode();
                        cronText = BackupCategoryEnum.AUTO_MINUTE.getMsg();
                        break;
                    default:
                        cron = BackupCategoryEnum.AUTO_HALF_HOUR.getCode();
                        cronText = BackupCategoryEnum.AUTO_HALF_HOUR.getMsg();
                        break;
                }

                BackupTask backupTask = new BackupTask();
                backupTask.setNodeId(reqVO.getNodeId());
                backupTask.setCron(cron);
                backupTask.setCronText(cronText);
                backupTask.setStatus(reqVO.getStatus());
                backupTask.setDatabaseName(reqVO.getDatabase());
                backupTask.setTablesName(StringUtils.join(reqVO.getTables(), ","));
                backupTask.setDataType(reqVO.getDataType());
                backupTask.setRemark(reqVO.getRemark());
                // 定时任务参数
                backupTask.setParam(jobVO);
                backupTaskMapper.insert(backupTask);
                // 添加定时任务
                quartzManager.add(backupTask.getId(), cron, JSON.toJSONString(backupTask.getParam()), backupTask.getStatus());
                return ResponseModel.success("操作成功，请在【任务管理】中查看");
            }
        } catch (Exception e) {
            return ResponseModel.fail("数据库备份失败：" + e.getMessage());
        }
    }

    /**
     * 组装备份参数
     */
    public BackupJobVO getBackupJobVO(NodeInfo nodeInfo, BackupReqVO reqVO) {
        BackupJobVO backupJobVO = new BackupJobVO();
        backupJobVO.setNodeId(nodeInfo.getId());
        backupJobVO.setHost(nodeInfo.getHost());
        backupJobVO.setPort(nodeInfo.getPort());
        backupJobVO.setUsername(nodeInfo.getUsername());
        backupJobVO.setPassword(nodeInfo.getPassword());
        backupJobVO.setDatabase(reqVO.getDatabase());
        backupJobVO.setTables(reqVO.getTables());
        backupJobVO.setDataType(reqVO.getDataType());
        backupJobVO.setIsCompress(reqVO.getIsCompress());
        backupJobVO.setIsUpload(reqVO.getIsUpload());
        backupJobVO.setIsDelete(reqVO.getIsDelete());
        return backupJobVO;
    }
}
